package sshDesktop

import (
	"fmt"
	"golang.org/x/crypto/ssh"
	"log"
	"my-desktop/config"
	"net"
	"time"
)

var DesktopSSHInputMap = make(map[string]chan string)  // 存放命令
var DesktopSSHOutputMap = make(map[string]chan string) // 存放命令执行结果

// 前端显示用的ssh连接
type DesktopSSH struct {
	UserID     uint64 `json:"userID"`
	ClientName string `json:"clientName"`

	Username    string `json:"username"`
	Password    string `json:"password"`
	IpAddress   string `json:"ipaddress"`
	Client      *ssh.Client
	Singer      ssh.Signer
	connTimeout time.Duration
	logger      *log.Logger
}

type DesktopSSHCache struct {
	UserID      uint64 `json:"userID"`
	ClientName  string `json:"clientName"`
	Username    string `json:"username"`
	Password    string `json:"password"`
	IpAddress   string `json:"ipaddress"`
	PrivateyKey string `json:"privateyKey"`
}

// NewWebSSH WebSSH 构造函数
func NewDesktopSSH() *DesktopSSH {
	return &DesktopSSH{
		logger:      DefaultLogger,
		connTimeout: DefaultConnTimeout,
	}
}

func (deskssh *DesktopSSH) SetLogger(logger *log.Logger) {
	deskssh.logger = logger
}

func (deskssh *DesktopSSH) SetUserName(username string) {
	deskssh.Username = username
}

func (deskssh *DesktopSSH) SetPassword(password string) {
	deskssh.Password = password
}

func (deskssh *DesktopSSH) SetIPAddress(ipAddress string) {
	deskssh.IpAddress = ipAddress
}

func (deskssh *DesktopSSH) SetUserID(userID uint64) {
	deskssh.UserID = userID
}

func (deskssh *DesktopSSH) SetClientName(name string) {
	deskssh.ClientName = name
}

// 建立连接
func (deskssh *DesktopSSH) CreateClient() error {
	var (
		//config       ssh.Config
		auth         []ssh.AuthMethod
		clientConfig *ssh.ClientConfig
		client       *ssh.Client
		err          error
	)

	sshConfig := ssh.Config{
		Ciphers: []string{"aes128-ctr", "aes192-ctr", "aes256-ctr", "aes128-gcm@openssh.com", "arcfour256", "arcfour128", "aes128-cbc", "3des-cbc", "aes192-cbc", "aes256-cbc"},
	}

	auth = make([]ssh.AuthMethod, 0)
	auth = append(auth, ssh.Password(deskssh.Password)) // 密码验证
	auth = append(auth, ssh.PublicKeys(deskssh.Singer)) // 密钥验证

	clientConfig = &ssh.ClientConfig{
		Config:          sshConfig,
		Auth:            auth,
		User:            deskssh.Username,
		Timeout:         deskssh.connTimeout,
		HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error { return nil },
	}

	addr := fmt.Sprintf("%s:%d", deskssh.IpAddress, config.Ssh.Port)
	//addr := fmt.Sprintf("%s:%d", deskssh.IpAddress, 22)
	if client, err = ssh.Dial("tcp", addr, clientConfig); err != nil {
		return err
	}
	deskssh.Client = client
	return nil
}
